
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
#include <log_fac.h>
#include <log_xml_format.h>
#include <queue>
#include <map>
#include <mutex>
#include <functional>
#include <thread>

using namespace std;

void log_init(void)
{
    string confFileName = {CMAKE_CURRENT_LIST_DIR};
    confFileName += "/log.conf";
    cout << "confFileName:" << confFileName << endl;
    LogFac::Instance().Init(confFileName);
}

struct Message
{
    int socket;
    string key;
    string msg;
};

using CallFunc = function<void(const Message &)>;

class MessageServer
{
private:
    map<string, CallFunc> callfunc_;
    queue<Message> msg_queue_;
    mutex msg_mutex_;
    bool exit_ = false;
    thread th_;

public:
    MessageServer() {}
    ~MessageServer() {}

    void Reg(string key, CallFunc func)
    {
        callfunc_[key] = func;
    }

    void Send(Message msg)
    {
        lock_guard<mutex> lock(mutex);
        msg_queue_.push(move(msg));
    }

    void Distribute(const Message &msg)
    {
        auto p = callfunc_.find(msg.key);
        if (p == callfunc_.end())
        {
            LOGERROR("方法未注册:" + msg.key)
            return;
        }
        p->second(msg);
    }

    void Run()
    {
        while (!exit_)
        {
            if (msg_queue_.empty())
            {
                this_thread::sleep_for(3s);
                continue;
            }
            Message msg;
            {
                lock_guard<mutex> lock(mutex);
                msg = msg_queue_.front();
                msg_queue_.pop();
            }
            Distribute(msg);
        }
        cout << "MessageServer Exit" << endl;
    }

    void Start()
    {
        this->exit_ = false;
        th_ = thread(&MessageServer::Run, this);
    }

    void Stop()
    {
        this->exit_ = true;
        if (th_.joinable())
        {
            th_.join();
        }
    }
};

class HttpServer : public MessageServer
{
private:
    void onGET(const Message &msg)
    {
        cout << "On GET: " << msg.msg << endl;
    }

    void onPOST(const Message &msg)
    {
        cout << "On POST: " << msg.msg << endl;
    }

public:
    HttpServer()
    {
        Reg("GET", [this](const Message &msg)
            { onGET(msg); });
        Reg("POST", [this](const Message &msg)
            { onPOST(msg); });
    }
    ~HttpServer() {}
};

int main(int argc, char const *argv[])
{
    // 初始化日志模块
    log_init();

    HttpServer server;

    // 服务启动前发送一些消息到队列中
    server.Send({1, "GET", "Hello"});
    server.Send({1, "GET", "wwww"});
    server.Send({1, "POST", "Hesfo"});

    server.Start();

    // 服务启动后再发送消息

    server.Send({1, "GET", "哈哈哈"});
    server.Send({1, "POST", "上传个文件"});

    // 等待 5秒
    this_thread::sleep_for(5s);

    // 停止服务
    server.Stop();

    return 0;
}
